package club.fuwenhao.handler;

import club.fuwenhao.bean.BaseMsg;
import club.fuwenhao.netty.BaseNettyServerHandler;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

/**
 * @program: fwh-netty
 * @description: fwh专属服务处理类--可以考虑扩展接口形式
 * @author: fwh
 * @date: 2021-10-29 10:43
 **/
@Slf4j
@ChannelHandler.Sharable
public class FwhNettyServerHandler extends BaseNettyServerHandler {
    int readIdleTimes = 0;

    /**
     * 必须实现类-接收消息
     *
     * @param ctx
     * @param msg
     * @return void
     * @author fuwenhao
     * @date 2021/10/29 10:44 上午
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, BaseMsg msg) throws Exception {
        log.info("FwhNettyServerHandler接收到消息为:{}", msg);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        readIdleTimes = 0;
        log.info("本地地址为:{},远程地址为:{},上线成功,重置readIdleTimes为0", ctx.channel().localAddress(), ctx.channel().remoteAddress());
    }

    /**
     * 服务端--心跳检测
     *
     * @param ctx
     * @param evt
     * @return void
     * @author fuwenhao
     * @date 2021/10/29 10:55 上午
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        IdleStateEvent event = (IdleStateEvent) evt;
        String eventType = null;
        switch (event.state()) {
            case READER_IDLE:
                eventType = "读空闲";
                readIdleTimes++; // 读空闲的计数加1
                break;
            case WRITER_IDLE:
                eventType = "写空闲";
                // 不处理
                break;
            case ALL_IDLE:
                eventType = "读写空闲";
                // 不处理
                break;
        }
        log.info("远程地址:{},超时事件为:{}", ctx.channel().remoteAddress(), eventType);
        if (readIdleTimes > 3) {
            log.info("远程地址:{}读空闲超过3次，关闭连接，释放更多资源", ctx.channel().remoteAddress());
            ctx.channel().writeAndFlush("idle close release resource");
            ctx.channel().close();
        }
    }
}
